/*
 *  Cero Project - Copyright   2006 The Cero Developement Team 
 *  (Michael Laguerre, Camille Roux, Matthieu Segret, Mathieu Sivade) 
 * 
 *  This program is free software; you can redistribute it and/or modify it 
 *  under the terms of the GNU General Public License as published by the Free 
 *  Software Foundation; either version 2 of the License, or (at your option) 
 *  any later version.
 * 
 *  This program is distributed in the hope that it will be useful, but 
 *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 *  for more details.
 */

package org.ceroproject.ui.graphical.tools.base;

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.ceroproject.games.*;
import org.ceroproject.ui.graphical.tools.*;
import org.ceroproject.ui.graphical.tools.layout.ZoneLayout;


/**
 * Class which creates a Graphical Zone associated with a Zone
 * 
 * @author Matt
 */
public class GraphicsZoneBase extends RectangleBase implements GraphicsZone {

	/* -------------- fields ------------- */

	/** Zone associate with the GraphicalZone */
	protected Zone zone;

	/** The ZoneLayout */
	protected ZoneLayout zoneLayout;
	
	/** Standard Color of the background zone */
	private Color colorBackGroundStandard;
	
	/** Background's color of a selected zone */
	private Color colorBackGroundSelected;
	
	/** Border size of the graphical zone */
	private int border;

	/** Selected Cards */
	private static List<GraphicsZone> selectedZones = new ArrayList<GraphicsZone>();

	/** HashMap stocking the Graphical Cards */
	private HashMap<Card,GraphicsCard> graphicsCardMap = new HashMap<Card,GraphicsCard>();

	
	
	/* ----------- Constructor ---------- */

	/**
	 * Build the GraphicalZone associated with the Zone
	 * 
	 * @param zone
	 *            the zone associated with the Graphical Zone
	 */
	public GraphicsZoneBase(Zone zone) {
		this.zone = zone;
		zone.addZoneListener(this);
		
		colorBackGroundStandard = Color.BLACK;
		colorBackGroundSelected = Color.WHITE;
		border = 50;

		// stock all graphicalCards of the zone
		for (Card c : zone.getSortedList()){
			graphicsCardMap.put(c, new GraphicsCardBase(c));
		}
	}
	
	
	/* ------------- Methods ------------- */

	/**
	 * Return the Zone associated with the GraphicalZone
	 * 
	 * @return the Zone associated with the GraphicalZone
	 */
	public Zone getZone() {
		return zone;
	}

	/**
	 * Get the ZoneLayout
	 * 
	 * @return the zoneLayout
	 */
	public ZoneLayout getZoneLayout() {
		return zoneLayout;
	}
	
	/**
	 * Set the ZoneLayout
	 * 
	 * @param zoneLayout
	 *            the ZoneLayout to set
	 */
	public void setZoneLayout(ZoneLayout zoneLayout) {
		this.zoneLayout = zoneLayout;
	}
	
	
	/**
	 * Get the graphical cards list
	 * 
	 * @return the graphical cards list
	 */
	public List<GraphicsCard> getGCardList() {
		List<GraphicsCard> gc = new ArrayList<GraphicsCard>();
		for (Card c : zone.getSortedList())
			gc.add(graphicsCardMap.get(c));
		return gc;
	}

	/**
	 * Return the status of the zone
	 * 
	 * @return true if the graphical Zone has been selected, false otherwise
	 */
	public boolean getSelected() {
		return selectedZones.contains(this);
	}

	/**
	 * Select the graphical Zone
	 * 
	 * @param state
	 *            true if the zone is selected, false otherwise
	 */
	public void setSelected(boolean state) {
		if (state)
			selectedZones.add(this);
		else
			selectedZones.remove(this);
	}
	
	
	/**
	 * This method gets called when a card got in the zone
	 * 
	 * @param from
	 *            The zone the card came from (may be null)
	 * @param to
	 *            The zone the card came in
	 * @param card
	 *            The card
	 */
	public void cardIn(Zone from, Zone to, Card card){
		graphicsCardMap.put(card, new GraphicsCardBase(card));
	}
	

	/**
	 * This method gets called when a card got out of the zone
	 * 
	 * @param from
	 *            The zone the card came from
	 * @param to
	 *            The zone the card came in (may be null)
	 * @param card
	 *            The card
	 */
	public void cardOut(Zone from, Zone to, Card card){
		graphicsCardMap.remove(card);
	}
	

	/**
	 * Return the coordinate of the GraphicsCard
	 * 
	 * @return the coordinate of the Rectangle
	 */
	public String toString() {
		return "name : " + getZone().getName() + super.toString();
	}
	
	
	/**
	 * Set the standard background's color
	 * 
	 * @param colorBackGroundStandard the color to set
	 */
	public void setbackGroundStandard(Color colorBackGroundStandard){
		this.colorBackGroundStandard = colorBackGroundStandard;
	}
	
	/**
	 * Set the selected background's color
	 * 
	 * @param colorBackGroundSelected the color to set
	 */
	public void setbackGroundSelected(Color colorBackGroundSelected){
		this.colorBackGroundSelected = colorBackGroundSelected;
	}
	
	/**
	 * Set the size of the border
	 * 
	 * @param border
	 * 				the border's size
	 */
	public void setBorder(int border) {
		this.border = border;
	}
	
	
	/**
	 * Paint the Zone background
	 * It is a colored rectangle which is black by default 
	 * 
	 * @param g
	 *            Graphics needed to paint the background
	 */
	protected void paintBackGroundStandard(Graphics g) {
		g.setColor(colorBackGroundStandard);
		g.fillRect(this.getX() + this.getWidth()/border, this.getY() + this.getHeight()/border,
				this.getWidth() - 2*this.getWidth()/border, this.getHeight() - 2*this.getHeight()/border);
	}

	/**
	 * Paint the Zone background
	 * It is a color rectangle which is white by default 
	 * 
	 * @param g
	 *            Graphics needed to paint the background
	 */
	protected void paintBackGroundSelected(Graphics g) {
		g.setColor(colorBackGroundSelected);
		g.fillRect(this.getX() + this.getWidth()/border, this.getY() + this.getHeight()/border,
				this.getWidth() - 2*this.getWidth()/border, this.getHeight() - 2*this.getHeight()/border);
	}
	
	
	/**
	 * Paint the cards
	 * 
	 * @param g
	 *            Graphics needed to paint the background
	 */
	protected void paintcards(Graphics g,Deck deck){
		for (Card card : zone.getSortedList()){
			if ( card != null )
				if (graphicsCardMap.get(card) != null)
					graphicsCardMap.get(card).paint(g,deck);
		}
	}
	
	
	/**
	 * Paint the GraphicalZone
	 * 
	 * @param g
	 *            Graphics needed to paint the GraphicalZone
	 */
	public void paint(Graphics g,Deck deck){
		// update the GraphicalCard position
		if (zoneLayout != null)
			zoneLayout.updateGraphicsCard(this);

		// paint the Zone background
		if (this.getSelected())
			paintBackGroundSelected(g);
		else
			paintBackGroundStandard(g);
		
		// painting the cards
		paintcards(g,deck);
	}
}
